unit oEditorStatisticsManager;

interface
uses oManager, oProcessItem, oProcessObjects, OpROCESSoBJECTcONSTANTS,
  oStatisticPRocessor, SysUtils, oFormStatistics, oFrameStatistics,
  oStatisticEventConstants, Generics.Collections, oLevel, oEntityTypeConstants,
  oScene, ComCtrls, Forms, Graphics, oEntity, oStatisticRepresentationConstants,
  classes, types, windows, dialogs, Teengine;

resourcestring
  sPedestrians = 'Pedestrians';
  sEntities = 'Entities';
  sArrivals = 'Arrivals';
  sWaitingTime = 'Waiting Time';
  sPeopleInModel = 'People in model';
  sPeopleInArrival = 'People in arrival';
  sAll = 'All';
  sMean = 'Mean';
  sDispersion = 'Dispersion';
  sReplication = 'Replication';

const
  cNone = 0;

  cCheckBUnChecked = 1;
  cCheckBChecked = 2;
  cCheckBBlock = 3;

  cRadioUnChecked = 4;
  cRadioChecked = 5;
  cRadioBlock = 6;


type

    EEditorStatisticsManager = class(Exception);

    TEditorStatisticsManager = class(TManager)
     private
      aEntityIds : Tlist<Integer>;
      aFrame : TfStatistics;
      aFlags : Tlist<Boolean>;
      aTree : TTreeView;
      aScene : TScene;
      aMain : TForm;
      aRepresentationType : integer;
      aStatisticType : integer;
      aStatTypeNodes : TList<TTreeNode>;
      aPedestrianNames, aArrivalNames : TStringlist;
      aStatProcessor : TStatisticPRocessor;
      procedure ToggleTreeViewCheckBoxes(node : TTreeNode);
      procedure prepareData;
      function isChecked(paLayer: String): Boolean;
      procedure onClick;
      procedure showChartStatistics(paChartType : integer;paTitle,
          paBottomTitle, paLeftTitle : string;
          paResults, paReplicationResults: TList<TStringStatisticPair>);
      procedure showGridStatistics(paName, paUnits : string;
                     paResults, paReplicationResults : TList<TStringStatisticPair>);
      procedure showMemoStatistics(paName, paUnits : string;
                     paResults, paReplicationResults : TList<TStringStatisticPair>);
      procedure saveGridToCSV(paFilename : String);
      function getChoiceForEntities(paName : string) : Tlist<Integer>;
      procedure getChoice(paGroup, paName : string; paNames, paList : TStringList);
      procedure Display(paType : integer);
      procedure saveMemoToTxt(paFileName : string);
      procedure showStatisticInGrid(paStat : TStringStatisticPair; paIndex : integer);
      procedure showStatisticInMemo(paStat : TStringStatisticPair; paUnits : string);
      procedure showOverallResultsTitle;
      procedure showRepResultsTitle;
      procedure ShowStatistic;
      procedure hideChart;
      function getStatisticType(paName : string) : integer;
     public
     constructor create(paMaster: TManager = nil);
      function ProcessObject(paItem: TProcessItem):TProcessItem; override;
      destructor Destroy; override;
      property Form : TForm read aMain write aMain;
    end;

implementation
uses oMasterManager, fmain;

{ TEditorStatisticsManager }

constructor TEditorStatisticsManager.create(paMaster: TManager);
begin
  aMaster := paMaster;
  aStatProcessor := TStatisticProcessor.Create;
  aRepresentationType := -1;
  aStatTypeNodes := TList<TTreenode>.create;
  aEntityIds := TList<integer>.Create;
  aStatisticType := -1;
  aMain := frmMain;
end;

destructor TEditorStatisticsManager.Destroy;
begin
  aStatProcessor.Free;
  aEntityIds.Free;
  aStatTypeNodes.Free;
  inherited;
end;

procedure TEditorStatisticsManager.Display(paType: integer);
var
  i : integer;
begin
  with aFrame do
  case aRepresentationType of
    SR_TABLE : begin
      memoStatistics.Visible := false;
      Chart.Visible := false;
      sdStatistic.Filter := 'Spreadsheet File|*.csv';
      for i := 0 to aFrame.StringGrid.ColCount - 1 do
       aFrame.StringGrid.Cols[i].Clear;
      lTitle.Visible := true;
      rgValues.Visible := false;
      rbMean.Visible := false;
      rbDispersion.Visible := false;
      StringGrid.Visible := true;
    end;
    SR_MEMO : begin
      memoStatistics.Visible := True;
      Chart.Visible := false;
      sdStatistic.Filter := 'Text File|*.txt';
      memoStatistics.Lines.Clear;
      rgValues.Visible := false;
      rbMean.Visible := false;
      rbDispersion.Visible := false;
      lTitle.Visible := true;
      StringGrid.Visible := false;
    end;
    SR_XY_CHART, SR_BAR_CHART, SR_PIE_CHART : begin
      memoStatistics.Visible := false;
      Chart.Visible := true;
      rgValues.Visible := true;
      rbMean.Visible := true;
      rbDispersion.Visible := true;
      sdStatistic.Filter := 'Image File|*.bmp';
      lTitle.Visible := False;
      StringGrid.Visible := false;
    end;
  end;
end;

function TEditorStatisticsManager.getChoiceForEntities(paName : string): Tlist<Integer>;
var
  node, temp, temp1, foundNode : TTreeNode;
  found : boolean;
  list : Tlist<Integer>;
begin
  found := false;
  foundNode := nil;
  list := nil;

  temp := aTree.Items.GetFirstNode;
  while (temp <> nil) and (not found) do
   begin
    temp1 := temp.getFirstChild;
    while (temp1 <> nil) and (not found) do
      begin
        if temp1.Text = paName then
          begin
            foundNode := temp1;
            found := true;
            break;
          end;
        temp1 := temp1.getNextSibling;
      end;
    temp := temp.getNextSibling;
   end;

  if foundNode <> nil then
   begin
    temp := foundNode.getFirstChild;
    list := TList<integer>.create;
    while temp <> nil do
     begin
        if temp.StateIndex = cCheckBChecked then
          list.Add(aEntityIds[temp.AbsoluteIndex]);
      end;
   end;

  Result := list;
end;

function TEditorStatisticsManager.getStatisticType(paName: string): integer;
begin
  if paName = sWaitingTime then
    aStatisticType := SE_WAITING_TIME_RESULT;
  if paName = sPeopleInModel then
    aStatisticType := SE_PEOPLE_IN_MODEL_RESULT;
  if paName = sPeopleInArrival then
    aStatisticType := SE_PEOPLE_IN_ARRIVAL_RESULT;
end;

procedure TEditorStatisticsManager.hideChart;
begin
  with aFrame do begin
    Chart.Visible := false;
    rgValues.Visible := false;
    rbMean.Visible := false;
    rbDispersion.Visible := false;
  end;
end;

procedure TEditorStatisticsManager.getChoice(paGroup, paName : string;
  paNames, paList : TStringList);
var
  node, temp, temp1, foundNode : TTreeNode;
  found : boolean;
begin
  found := false;
  foundNode := nil;
  paList.Clear;

  temp := aTree.Items.GetFirstNode;
  while (temp <> nil) and (not found) do
   begin
     if temp.Text = paGroup then
        begin
          foundNode := temp;
          found := true;
          break;
        end;
    temp := temp.getNextSibling;
   end;

  if foundNode <> nil then
   begin
    temp := foundNode.getFirstChild;
    found := false;
    while (temp <> nil) and (not found) do
     begin
       if temp.Text = paName then
          begin
            foundNode := temp;
            found := true;
            break;
          end;
      temp := temp.getNextSibling;
     end;

    temp := foundNode.getFirstChild;
    if temp.StateIndex = cCheckBChecked then
      paList.Add(sAll)
    else
      begin
       temp := temp.getNextSibling;
       while temp <> nil do
        begin
           if temp.StateIndex = cCheckBChecked then
             paList.Add(paNames[foundNode.IndexOf(temp) - 1]);
           temp := temp.getNextSibling;
         end;
        end;
      end;

end;

procedure TEditorStatisticsManager.onClick;
var
  p : Tpoint;
begin
  GetCursorPos(P);
  P := aTree.ScreenToClient(P);
  if (htOnStateIcon in
             aTree.GetHitTestInfoAt(P.X,P.Y)) then
  begin
    ToggleTreeViewCheckBoxes(aTree.Selected);
    exit;
  end
   // END   checkbox
  else
  begin
    getStatisticType(aTree.Selected.Text);
    ShowStatistic;
  end;
end;

procedure TEditorStatisticsManager.prepareData;
var
  j: Integer;
  level : Tlevel;
  log : TEntity;
  root, node, node1, node2 : TTreeNode;
  nodes : TList<TTreeNode>;
  item : TProcessItem;
  arrNames : TStringList;
begin

  aPedestrianNames := TStringList.Create;
  for j := 0 to aStatProcessor.WaitingTimesResult.Count - 1 do
    aPedestrianNames.Add(aStatProcessor.WaitingTimesResult[j].Key);

  aArrivalNames := TStringList.Create;
  for j := 0 to aStatProcessor.ArrivalCountsResults.Count - 1 do
    aArrivalNames.Add(aStatProcessor.ArrivalCountsResults[j].Key);

  with aFrame do
   begin

    cbReplications.Clear;
    cbReplications.AddItem(sAll, TInteger.Create(-1));
    for j := 1 to aStatProcessor.ReplicationCount do
        cbReplications.AddItem(sReplication + ' ' + IntToStr(j), TInteger.Create(j));
    cbReplications.ItemIndex := 0;

    aStatProcessor.Replication := -1;

    tvStatObjects.Items.Clear;

    root := tvStatObjects.Items.GetFirstNode;
    root := tvStatObjects.Items.AddChild(root, sEntities);
    aEntityIds.Add(-1);
    nodes := TList<TTreeNode>.Create;

    for j := 0 to Length(ET_NAMES) - 2 do
     begin
      node := tvStatObjects.Items.AddChild(root, ET_NAMES[J]);
      node.StateIndex := cRadioUnChecked;
      aEntityIds.Add(-1);
      nodes.Add(node);
     end;

    root := tvStatObjects.Items.GetFirstNode;
    node := aTree.Items.Add(root, sPedestrians);

    node1 := aTree.Items.AddChild(node, sPeopleInModel);

    node1 := aTree.Items.AddChild(node, sWaitingTime);

    nodes.Add(node1);
    aEntityIds.Add(-1);

    for node in nodes do
    begin
      node1 := tvStatObjects.Items.AddChild(node, sAll);
      node1.StateIndex := cCheckBChecked;
      aEntityIds.Add(-1);
    end;

    for level in aScene.Levels do
    begin
      for j := 0 to level.AllLogicalEntities.Count -1 do
        begin
         node := tvStatObjects.Items.AddChild(nodes[level.AllLogicalEntities[j].TypeLogic],
         level.AllLogicalEntities[j].Name + IntToStr(j));
         node.StateIndex := cCheckBUnChecked;
         aEntityIds.Add(level.AllLogicalEntities[j].Id);
        end;
    end;


   for j := 0 to aStatProcessor.WaitingTimesResult.Count - 1 do
    begin
     node := tvStatObjects.Items.AddChild(nodes[ET_PEDESTRIAN], aStatProcessor.WaitingTimesResult[j].Key);
     node.StateIndex := cCheckBUnChecked;
    end;

   item := aMaster.ProcessObject(TProcessItem.create(PO_ARRMAN_GET_NAMES, nil));

   root := tvStatObjects.Items.GetFirstNode;
   node := aTree.Items.Add(root, sArrivals);
   node := aTree.Items.AddChild(node, sPeopleInArrival);
   aStatTypeNodes.Add(node);
   nodes.Add(node);
   node1 := aTree.Items.AddChild(node, sAll);
   node1.StateIndex := cCheckBChecked;

   for j := 0 to aStatProcessor.ArrivalCountsResults.Count - 1 do
     begin
      node1 := aTree.Items.AddChild(node, aStatProcessor.ArrivalCountsResults[j].Key);
      node1.StateIndex := cCheckBUnChecked;
     end;
   end;
end;

function TEditorStatisticsManager.isChecked(paLayer: String): Boolean;
var
  node : TTreeNode;
  checked : Boolean;
begin
  checked := False;
  while (Assigned(node) and (checked = False)) do
  begin
    if node.StateIndex in [cRadioChecked, cCheckBChecked] then
      checked := True;
    node := node.getNextSibling;
  end;
  Result := checked;
end;

procedure TEditorStatisticsManager.ToggleTreeViewCheckBoxes(
   Node:TTreeNode);

   procedure Zaklikni(node:TTreeNode);
   var
     tmp:TTreeNode;
   begin
      tmp := Node.Parent.getFirstChild;
      while Assigned(tmp) do
      begin
        if tmp.StateIndex = cRadioUnChecked then
        begin
          tmp.StateIndex := cRadioBlock;
        end;
        tmp := tmp.getNextSibling;
      end;
      Node.StateIndex := cRadioChecked;

        // oznamenie managerom ze sa zakliklo a treba to nacitat


        // odblokuj dalsi stupen
      tmp := Node.Parent.getNextSibling;
      if Assigned(tmp) then
      begin
        tmp := tmp.getFirstChild;
        if Assigned(tmp) then
          begin
{          if (tmp.Parent.Text = sData5) and (not isChecked(sData3)) then
            tmp := nil
          else if (tmp.Parent.Text = sData4) then
          begin
            if (isChecked(sData4)) then
              tmp := LayerToNode(sData5).getFirstChild
            else
              tmp := nil;
        end;}
        end;
        while Assigned(tmp) do
        begin
          if tmp.StateIndex = cRadioBlock then
          begin
            tmp.StateIndex := cRadioUnChecked;
          end;
          tmp := tmp.getNextSibling;
        end;
      end;
   end;

   procedure Odklikni(node:TTreeNode);
   var
     tmp, parent:TTreeNode;
   begin
      tmp := Node.Parent;
      if not Assigned(tmp) then
        tmp := TTreeView(Node.TreeView).Items.getFirstNode
      else
        tmp := tmp.getFirstChild;
      while Assigned(tmp) do
      begin
        if (tmp.StateIndex in
                   [cRadioBlock, cRadioChecked]) then
        begin
          tmp.StateIndex := cRadioUnChecked;
        end;
        tmp := tmp.getNextSibling;
      end;

        // oznamenie managerom ze sa odkliklo a treba to vyhodit s pamete
      //onUnchecked(Node);

       // zablokuj dalsie stupene
      parent := Node.Parent.getNextSibling;
//      if ((Assigned(parent)) and (parent.Text = sData4)) then
  //        parent := parent.getNextSibling;
      tmp := parent;
      while Assigned(tmp) do
      begin
        tmp := tmp.getFirstChild;
        while Assigned(tmp) do
        begin
          if (tmp.StateIndex in
                   [cRadioUnChecked, cRadioChecked]) then
          begin
{            if (parent.Text = sData4) then
              tmp.StateIndex := cRadioUnChecked
            else
              tmp.StateIndex := cRadioBlock;}
          end;
          tmp := tmp.getNextSibling;
        end;
//        showSubLayer(parent.Text);
        parent := parent.getNextSibling;
//        if ((Assigned(parent)) and (parent.Text = sData4)) then
  //        parent := parent.getNextSibling;
        tmp := parent;
      end;
   end;

var
  unchecked: TTreeNode;
  found: boolean;
  j: Integer;
begin
  if Assigned(Node) then
  begin


    if Node.StateIndex = cRadioUnChecked then // zaskrtnut
    begin
      Zaklikni(node);
    end // if StateIndex = cRadioUnChecked
    else
    if Node.StateIndex = cRadioChecked then  // odskrtnut
    begin
      Odklikni(node);
    end
    else
    if (Node.StateIndex = cRadioBlock) and (isChecked(Node.Parent.Text)) then  // odskrtnut
    begin
      unchecked := Node.Parent.getFirstChild;
      found := False;
      while ((Assigned(unchecked)) and (not found)) do
      begin
        if unchecked.StateIndex = cRadioChecked then
          found := true
        else
          unchecked := unchecked.getNextSibling;
      end;
      Odklikni(unchecked);
      Zaklikni(node);
    end

    else
    if Node.StateIndex = cCheckBUnChecked then // zaskrtnut
    begin
      if node.Parent <> nil then
       begin
        getStatisticType(node.Parent.Text);
        ShowStatistic;
       end;
      Node.StateIndex := cCheckBChecked;
      if node.Parent.IndexOf(node) = 0 then
       begin
          unchecked := node.Parent.getFirstChild.getNextSibling;
          while unchecked <> nil do
            begin
              unchecked.StateIndex := cCheckBUnChecked;
              unchecked := unchecked.getNextSibling;
            end;
       end
     else
      node.Parent.getFirstChild.StateIndex := cCheckBUnChecked;

        // oznamenie managerom ze sa zakliklo a treba to nacitat
      //onChecked(Node);
    end // if StateIndex = cCheckBUnChecked
    else
    if Node.StateIndex = cCheckBChecked then  // odskrtnut
    begin
      Node.StateIndex := cCheckBUnChecked;

        // oznamenie managerom ze sa odkliklo a treba to vyhodit s pamete
     // onUnchecked(Node);
    end;
  end; // if Assigned(Node)
  ShowStatistic;
end;

function TEditorStatisticsManager.ProcessObject(
  paItem: TProcessItem): TProcessItem;
var
  list : TprocessingList;
  form : TForm2;
  typ : integer;
  j: Integer;
  item : TProcessItem;
  value : TInteger;
  i: TfStatistics;
  meta : TMetafile;
begin

  if paItem.Data is TProcessingList then
    list := TProcessingList(paItem.Data)
    else
      if paItem.Data is TInteger then
        value := TInteger(paItem.Data);

  case paItem.Code of
    PO_EDITOR_STAT_SET_PARAMS : begin
      aStatProcessor.ReplicationCount := TInteger(list.Parameters[0]).Integer_;
      aStatProcessor.Path := TString(list.Parameters[1]).String_;
      aFlags := TProcessingBoolList(list.Parameters[2]).List;
    end;

    PO_EDITOR_STAT_SHOW : begin
      form := TForm2.Create(nil);
      aFrame := form.TfStatistics1;
      aScene := TMasterManager(aMaster).SceneManager.Scene;
      aTree := aFrame.tvStatObjects;

      form.Manager := Self;
      prepareData;
      aFrame.Manager := self;
      form.Show;
    end;

    PO_EDITOR_STAT_COMPUTE : begin
      aStatProcessor.processStatistics(aFlags);
    end;

    PO_EDITOR_STAT_SINGLE_SAVE : begin
      with aFrame do
       begin
         if sdStatistic.Execute then
           case aRepresentationType of
             SR_TABLE : begin
                saveGridToCSV(sdStatistic.FileName);
             end;
             SR_XY_CHART, SR_BAR_CHART, SR_PIE_CHART : begin
                Chart.SaveToBitmapFile(sdStatistic.FileName + '.bmp');
             end;

             SR_MEMO : begin
                saveMemoToTxt(sdStatistic.FileName);
             end;
           end;
       end;
    end;

    PO_EDITOR_STAT_SHOW_STATISTIC : begin
       ShowStatistic;
    end;

    PO_EDITOR_STAT_SET_REPLICATION : begin
      if value.Integer_ <> -1 then
        aStatProcessor.Replication := value.Integer_ - 1
      else aStatProcessor.Replication := value.Integer_;
      ShowStatistic;
    end;

    PO_EDITOR_STAT_LOAD : begin
      if (paItem.Data = nil) then
        raise EEditorStatisticsManager.Create('Nil input');
      aStatProcessor.LoadFromXML(TString(paItem.Data).String_);
      (aMain as TfrmMain).StatisticsView.Enabled := true;
    end;

    PO_EDITOR_STAT_SAVE : begin
      if (paItem.Data = nil) then
        raise EEditorStatisticsManager.Create('Nil input');
      aStatProcessor.SaveToXML(TString(paItem.Data).String_);
    end;

    PO_EDITOR_STAT_REPR_TYPE : begin
      if value <> nil then
        aRepresentationType := value.Integer_;
      ShowStatistic;
    end;

    PO_EDITOR_STAT_TREE_CLICK : begin
      onClick;
    end
   else
    raise EEditorStatisticsManager.Create('Could not process message');
  end;

end;

procedure TEditorStatisticsManager.saveGridToCSV(paFilename: String);
var
  f : text;
  i, j : integer;
begin
  Assign(f, paFilename + '.csv');
  Rewrite(f);
  with aFrame.StringGrid do
   begin
    for j := 0 to RowCount - 1 do
     begin
      for i := 0 to ColCount - 2 do
        write(f, Cells[i, j] + ';');
      Write(f, Cells[ColCount - 1, j]);
      writeln(f);
     end;
   end;

  Close(f);
end;

procedure TEditorStatisticsManager.saveMemoToTxt(paFileName: string);
var
  f : text;
  j: Integer;
begin
  Assign(f, paFileName + '.txt');
  Rewrite(f);
  for j := 0 to aFrame.memoStatistics.Lines.Count - 1 do
    writeln(f, aFrame.memoStatistics.Lines[j]);

  Close(f);
end;

procedure TEditorStatisticsManager.showChartStatistics(paChartType : integer;
  paTitle, paBottomTitle, paLeftTitle : string;
  paResults, paReplicationResults: TList<TStringStatisticPair>);

  function getValue(paResults : TList<TStringStatisticPair>;
        paIndex : integer) : real;
   begin
     Result := 0;
     if aFrame.rbMean.Checked then
      Result := paResults[paIndex].Value.Mean;
     if aFrame.rbDispersion.Checked then
      Result := paResults[paIndex].Value.Dispersion;
   end;

   procedure showTitles;
   begin
     aFrame.Chart.Title.Caption := paTitle;
     aFrame.Chart.BottomAxis.Title.Caption := paBottomTitle;

     aFrame.Chart.LeftAxis.Title.Caption := aFrame.Chart.LeftAxis.Title.Caption +
        paLeftTitle;
   end;

   procedure Clear;
   var
    i : integer;
   begin
    with aFrame.Chart do begin
     for i := 0 to aFrame.Chart.SeriesList.Count - 1 do
      aFrame.Chart.Series[i].Clear;
     Title.Caption := '';
     BottomAxis.Title.Caption := '';
     LeftAxis.Title.Caption := '';
     Axes.Visible := true;
    end;
   end;
var
  i, j : integer;
  value : real;
  title : TChartAxisTitle;
begin

  Clear;
  with aFrame.Chart.Series[paChartType] do
   begin
     Clear;

     if paChartType <> SR_PIE_CHART then
      showTitles
     else
      begin
        aFrame.Chart.Title.caption := paTitle + ' ' + paLeftTitle;
        aFrame.Chart.Axes.Visible := false;
      end;

    if aStatProcessor.Replication = -1 then
     if aStatProcessor.StringChoice <> nil then
       if aStatProcessor.StringChoice.Count > 0 then
         if aStatProcessor.StringChoice[0] <> sAll then
            for j := 0 to paResults.Count - 1 do
             for i := 0 to aStatProcessor.StringChoice.Count - 1 do
              begin
               if aStatProcessor.StringChoice[i] = paResults[j].Key then
                  Add(getValue(paResults, j), paResults[j].Key)
              end
          else
            for j := 0 to paResults.Count - 1 do
             Add(getValue(paResults, j), paResults[j].Key);


    if aStatProcessor.Replication >= 0 then    // only one replication
      begin
        aFrame.Chart.Title.Caption := aFrame.Chart.Title.Caption + ' in rep. ' +
            IntToStr(aStatProcessor.Replication + 1);

      if aStatProcessor.StringChoice <> nil then
       if aStatProcessor.StringChoice.Count > 0 then
        if aStatProcessor.StringChoice[0] <> sAll then
         begin
          for j := 0 to paReplicationResults.Count - 1 do
           for i := 0 to aStatProcessor.StringChoice.Count - 1 do
            if paReplicationResults[j].Key =
              aStatProcessor.StringChoice[i] then
               Add(getValue(paReplicationResults, j), paReplicationResults[j].Key);
           end
         else
       for j := 0 to paReplicationResults.Count - 1 do
         Add(getValue(paReplicationResults, j), paReplicationResults[j].Key);
     end;

   end;
end;

procedure TEditorStatisticsManager.showStatisticInGrid(paStat : TStringStatisticPair; paIndex : integer);
  var
    item : TProcessItem;
  begin

     with aFrame.StringGrid do
       begin
        Cells[0, paIndex + 1] := paStat.Key;
        Cells[1, paIndex + 1] := FormatFloat('0.000', paStat.Value.Mean);
        Cells[2, paIndex + 1] := FormatFloat('0.000', paStat.Value.Dispersion);
       end;

end;

procedure TEditorStatisticsManager.showStatisticInMemo(
  paStat: TStringStatisticPair; paUnits : string);
begin
  aFrame.memoStatistics.Lines.Add(paStat.Key);
  aFrame.memoStatistics.Lines.Add('Mean: ' + FormatFloat('0.000', paStat.Value.Mean) + paUnits);
  aFrame.memoStatistics.Lines.Add('Dispersion: ' + FormatFloat('0.000', paStat.Value.Dispersion) + paUnits);
  aFrame.memoStatistics.Lines.Add('');
end;

procedure TEditorStatisticsManager.showGridStatistics(paName, paUnits : string;
  paResults, paReplicationResults : TList<TStringStatisticPair>);

var
  j, i : integer;
  item : TProcessItem;
begin

  if paResults <> nil then
    showOverallResultsTitle
  else
    showRepResultsTitle;

  aFrame.StringGrid.RowCount := 1;
  aFrame.StringGrid.ColCount := 3;
  aFrame.StringGrid.Cells[0, 0] := paName;
  aFrame.StringGrid.Cells[1, 0] := 'Mean';
  aFrame.StringGrid.Cells[2, 0] := 'Dispersion';
  aFrame.StringGrid.FixedCols := 0;



  if aStatProcessor.Replication = -1 then  // all replications
   begin

    if aStatProcessor.StringChoice <> nil then
     if aStatProcessor.StringChoice.Count > 0 then
      if aStatProcessor.StringChoice[0] <> sAll then
        begin
        for j := 0 to paResults.Count - 1 do
         for i := 0 to aStatProcessor.StringChoice.Count - 1 do
         if aStatProcessor.StringChoice[i] = paResults[j].Key then
          begin
           aFrame.StringGrid.RowCount := aFrame.StringGrid.RowCount + 1;
           showStatisticInGrid(paResults[j], i);
          end
        end
      else
        for j := 0 to paResults.Count - 1 do
         begin
          aFrame.StringGrid.RowCount := aFrame.StringGrid.RowCount + 1;
          showStatisticInGrid(paResults[j], j);
         end
   end
  else
    begin
    // only one replication
    if aStatProcessor.StringChoice <> nil then
     if aStatProcessor.StringChoice.Count > 0 then
      if aStatProcessor.StringChoice[0] <> sAll then
       begin
        for j := 0 to paReplicationResults.Count - 1 do
         for i := 0 to aStatProcessor.StringChoice.Count - 1 do
          if paReplicationResults[j].Key =
            aStatProcessor.StringChoice[i] then
            begin
             aFrame.StringGrid.RowCount := aFrame.StringGrid.RowCount + 1;
             showStatisticInGrid(paReplicationResults[j], i);
            end
       end
    else
     for j := 0 to paReplicationResults.Count - 1 do
      begin
       aFrame.StringGrid.RowCount := aFrame.StringGrid.RowCount + 1;
       showStatisticInGrid(paReplicationResults[j], j);
      end;
   end;

   if aFrame.StringGrid.RowCount = 1 then
    aFrame.StringGrid.RowCount := aFrame.StringGrid.RowCount + 1;
   aFrame.StringGrid.FixedRows := 1;


end;

procedure TEditorStatisticsManager.showMemoStatistics(paName, paUnits: string;
paResults, paReplicationResults: TList<TStringStatisticPair>);
var
  i, j : integer;
begin
  if paResults <> nil then
    showOverallResultsTitle
  else
    showRepResultsTitle;

 aFrame.memoStatistics.Lines.Add(paName);
 aFrame.memoStatistics.Lines.Add('');

 if aStatProcessor.Replication = -1 then  // all replications
   begin

    if aStatProcessor.StringChoice <> nil then
     if aStatProcessor.StringChoice.Count > 0 then
      if aStatProcessor.StringChoice[0] <> sAll then
        begin
        for j := 0 to paResults.Count - 1 do
         for i := 0 to aStatProcessor.StringChoice.Count - 1 do
         if aStatProcessor.StringChoice[i] = paResults[j].Key then
           showStatisticInMemo(paResults[j], paUnits);
        end
      else
        for j := 0 to paResults.Count - 1 do
          showStatisticInMemo(paResults[j], paUnits);
   end
  else
    begin
    // only one replication
    if aStatProcessor.StringChoice <> nil then
     if aStatProcessor.StringChoice.Count > 0 then
      if aStatProcessor.StringChoice[0] <> sAll then
       begin
        for j := 0 to paReplicationResults.Count - 1 do
         for i := 0 to aStatProcessor.StringChoice.Count - 1 do
          if paReplicationResults[j].Key =
            aStatProcessor.StringChoice[i] then
             showStatisticInMemo(paReplicationResults[j], paUnits);
       end
    else
     for j := 0 to paReplicationResults.Count - 1 do
       showStatisticInMemo(paReplicationResults[j], paUnits);
   end;

end;

procedure TEditorStatisticsManager.showOverallResultsTitle;
begin
  aFrame.lTitle.Caption := 'Overall results';
end;

procedure TEditorStatisticsManager.showRepResultsTitle;
begin
  aFrame.lTitle.Caption := 'Results in rep.' +
      IntToStr(aStatProcessor.Replication + 1);
end;

procedure TEditorStatisticsManager.ShowStatistic;
begin
   Display(aRepresentationType);

   if aStatProcessor.Replication >= 0 then
    showRepResultsTitle
   else
    showOverallResultsTitle;

   case aStatisticType of
    SE_WAITING_TIME_RESULT : begin

      getChoice(sPedestrians, sWaitingTime,
          aPedestrianNames, aStatProcessor.StringChoice);

      case aRepresentationType of

       SR_TABLE : begin
        with aFrame do
         begin
           if aStatProcessor.WaitingTimesResult.Count > 0 then
            if aStatProcessor.Replication >= 0 then
              showGridStatistics('Pedestrians', '[s]',nil,
                aStatProcessor.ReplicationStats[aStatProcessor.Replication].WaitingTimes)
            else
              showGridStatistics('Pedestrians', '[s]',aStatProcessor.WaitingTimesResult,
                nil)
           else
            raise EEditorStatisticsManager.Create('No results to display');
         end;

       end;

       SR_BAR_CHART : begin
         with aFrame do begin
          if aStatProcessor.WaitingTimesResult.Count > 0 then
           if aStatProcessor.Replication >= 0 then
            showChartStatistics(aRepresentationType, 'Waiting time', 'Pedestrians', '[s]',
                  nil,
                  aStatProcessor.ReplicationStats[aStatProcessor.Replication].WaitingTimes)
           else
            showChartStatistics(aRepresentationType, 'Waiting time', 'Pedestrians', '[s]',
                  aStatProcessor.WaitingTimesResult,
                  nil)
          else
            raise EEditorStatisticsManager.Create('No results to display');
          end;
       end;

       SR_MEMO : begin
        with aFrame.memoStatistics do
         begin
          if aStatProcessor.WaitingTimesResult.Count > 0 then
           if aStatProcessor.Replication >= 0 then
            showMemoStatistics('Waiting times', '[s]',
                  nil,
                  aStatProcessor.ReplicationStats[aStatProcessor.Replication].WaitingTimes)
           else
            showMemoStatistics('Waiting times', '[s]',
                  aStatProcessor.WaitingTimesResult,
                  nil)
          else
            raise EEditorStatisticsManager.Create('No results to display');
         end;
       end
      else
       begin
        hideChart;
//        raise EEditorStatisticsManager.Create('Type not supported yet');
       end;
      end;

    end;

    SE_PEOPLE_IN_MODEL_RESULT : begin
      with aFrame do
        case aRepresentationType of
         SR_MEMO : begin

            if aStatProcessor.Replication = -1 then
             begin
              memoStatistics.Lines.Add('People in model');
              memoStatistics.Lines.Add('Mean: '
               + FormatFloat('0.000', aStatProcessor.PeopleInModelResult.Mean));
              memoStatistics.Lines.Add('Dispersion: '
               + FormatFloat('0.000', aStatProcessor.PeopleInModelResult.Dispersion));
             end
            else
             begin
              memoStatistics.Lines.Add('People in model');
              memoStatistics.Lines.Add('Mean: '
               + FormatFloat('0.000', aStatProcessor.PeopleInModel.Values[aStatProcessor.Replication]));
             end;
         end;

         SR_TABLE : begin
           with StringGrid do begin
            RowCount := 2; ColCount := 2;
            FixedCols := 0; FixedRows := 1;
            Cells[0, 0] := 'People';
            Cells[1, 0] := 'Mean';
           if aStatProcessor.Replication = -1 then
            begin
             ColCount := 3;
             Cells[2, 0] := 'Dispersion';
             StringGrid.Cells[1, 1] := FormatFloat('0.000', aStatProcessor.PeopleInModelResult.Mean);
             StringGrid.Cells[2, 1] := FormatFloat('0.000', aStatProcessor.PeopleInModelResult.Dispersion);
            end
           else
            begin
             StringGrid.Cells[1, 1] := FormatFloat('0.000', aStatProcessor.PeopleInModel.Values[aStatProcessor.Replication]);
            end;
           end;
         end
        else
         begin
           hideChart;
 //          raise EEditorStatisticsManager.Create('Type not supported yet');
         end;

        end;

    end;


    SE_PEOPLE_IN_ARRIVAL_RESULT : begin

     getChoice(sArrivals, sPeopleInArrival,
            aArrivalNames, aStatProcessor.StringChoice);

      case aRepresentationType of
        SR_BAR_CHART, SR_PIE_CHART : begin
          with aFrame do begin
          if aStatProcessor.ArrivalCountsResults.Count > 0 then
           if aStatProcessor.Replication >= 0 then
            showChartStatistics(aRepresentationType, 'People in arrivals', 'Arrivals', '[persons]',
                  nil,
                  aStatProcessor.ReplicationStats[aStatProcessor.Replication].ArrivalCounts)
           else
            showChartStatistics(aRepresentationType, 'People in arrivals', 'Arrivals', '[persons]',
                  aStatProcessor.ArrivalCountsResults,
                  nil)
          else
            raise EEditorStatisticsManager.Create('No results to display');
          end;
        end;

        SR_TABLE :
          begin
            with aFrame do begin
               memoStatistics.Visible := false;
               StringGrid.Visible := true;
               if aStatProcessor.ArrivalCountsResults.Count > 0 then
                if aStatProcessor.Replication >= 0 then
                  showGridStatistics('Arrival', '[s]',nil,
                    aStatProcessor.ReplicationStats[aStatProcessor.Replication].ArrivalCounts)
                else
                  showGridStatistics('Arrival', '[s]', aStatProcessor.ArrivalCountsResults,
                    nil)
               else
                raise EEditorStatisticsManager.Create('No results to display');
             end;
          end;

        SR_MEMO : begin
           with aFrame.memoStatistics do
             begin
              if aStatProcessor.ArrivalCountsResults.Count > 0 then
               if aStatProcessor.Replication >= 0 then
                showMemoStatistics('People in arrivals', '[persons]',
                      nil,
                      aStatProcessor.ReplicationStats[aStatProcessor.Replication].ArrivalCounts)
               else
                 showMemoStatistics('People in arrivals', '[persons]',
                      aStatProcessor.ArrivalCountsResults,
                      nil)
              else
                raise EEditorStatisticsManager.Create('No results to display');
             end
        end
       else
 //       raise EEditorStatisticsManager.Create('Type not supported yet');

      end;

    end;
  end;
end;

end.

